import 'dart:math';

import 'package:flutter/material.dart';


/// ⚠️direction目前切换方向需要重新运行才会正常，不要代码动态控制方向切换
class IntlWidget extends StatefulWidget {
  final Widget child;

  /// 动画方向, horizontal时要设置maxWidth才有效， vertical时要设置maxHeight才有效
  final Axis direction;
  //
  // /// 固定宽
  // final double? width;
  //
  // /// 固定高
  // final double? height;

  /// 最大宽
  final double? maxWidth;

  /// 最大高
  final double? maxHeight;

  const IntlWidget(
      {super.key,
      required this.child,
      this.direction = Axis.horizontal,
      // this.width,
      // this.height,
      this.maxWidth,
      this.maxHeight});

  @override
  State<IntlWidget> createState() => _IntlWidgetState();
}

class _IntlWidgetState extends State<IntlWidget>
    with SingleTickerProviderStateMixin {
   GlobalKey _key = GlobalKey();

  AnimationController? _controller;
  Animation<double>? _animation;

  double? _autoWidth;

  set autoWidth(double value) {
    if (widget.maxWidth != null) {
      _autoWidth = min(value, widget.maxWidth!);
    } else {
      _autoWidth = value;
    }
  }

  double get autoWidth {
    // if (widget.width != null) {
    //   return widget.width!;
    // }
    return _autoWidth ?? 0;
  }

  double? _autoHeight;

  set autoHeight(double value) {
    if (widget.maxHeight != null) {
      _autoHeight = min(value, widget.maxHeight!);
    } else {
      _autoHeight = value;
    }
  }

  double get autoHeight {
    // if (widget.height != null) {
    //   return widget.height!;
    // }
    return _autoHeight ?? 0;
  }

  Size? _contentSize;

  /// 动画偏移值
  double offsetX = 0, offsetY = 0;

  /// 是否缩放
  bool scaleDown = false;

  /// 横向差值范围小于此值时做缩放
  final scaleDownValue = 6;

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      final renderBox = _key.currentContext?.findRenderObject() as RenderBox?;
      if (renderBox != null) {
        final size = renderBox.size;
        checkAnimate(size);
      }
    });
  }



  @override
  Widget build(BuildContext context) {
    return Container(
      // color: Colors.green,
      width: autoWidth,
      height: autoHeight,
      child: scaleDown
          ? FittedBox(
        fit: BoxFit.scaleDown,
        child: Container(
          key: _key,
          child: widget.child,
        ),
      )
          : Stack(
        // clipBehavior: Clip.none,
        children: [
          Positioned(
              top: offsetY,
              left: offsetX,
              // width: widget.direction == Axis.horizontal
              //     ? null
              //     : _autoWidth,//(widget.width ?? _autoWidth),
              // height: widget.direction == Axis.vertical
              //     ? null
              //     : _autoHeight,//(widget.height ?? _autoHeight),
              child: Container(
                key: _key,
                child: widget.child,
              ))
        ],
      ),
    );
  }


  @override
  void didUpdateWidget(covariant IntlWidget oldWidget) {
    if (oldWidget.direction != widget.direction) {
    //   direction = true;
    //   offsetY = 0;
    //   offsetX = 0;
    //   setState(() {});
    //   direction = false;
    //   setState(() {});
    }
    super.didUpdateWidget(oldWidget);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final renderBox = _key.currentContext?.findRenderObject() as RenderBox?;
      if (renderBox != null) {
        final size = renderBox.size;
        checkAnimate(size);
      }
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  checkAnimate(Size contentSize) {
    _contentSize = contentSize;
    // if (widget.direction == )

    double? startAnimateWidth = widget.maxWidth;// ?? widget.width;
    double? startAnimateHeight = widget.maxHeight;// ?? widget.height;
    // print('child 宽度: ${contentSize.width};;;$startAnimateWidth, 高度: ${contentSize.height};; $startAnimateHeight');
    if (widget.direction == Axis.horizontal &&
        startAnimateWidth != null &&
        contentSize.width > startAnimateWidth) {
      _controller?.stop();
      final animateValue = contentSize.width - startAnimateWidth;

      autoWidth = startAnimateWidth;
      autoHeight = contentSize.height;
      scaleDown = animateValue.abs() < scaleDownValue;
      offsetY = (autoHeight - contentSize.height) * 0.5;
      // print("开始动画 scaleDownValue = $scaleDownValue");
      if (scaleDown) {
        offsetX = 0;
        setState(() {});
        return;
      }
      // print("开始动画 scaleDown = $scaleDown");
      final animateSec = (animateValue / 10).ceil();
      _controller ??= AnimationController(
        vsync: this,
      );
      _controller?.duration = Duration(seconds: animateSec);
      _animation?.removeListener(_updateOffsetX);
      _animation?.removeListener(_updateOffsetY);
      _animation =
          Tween<double>(begin: 0.0, end: animateValue).animate(CurvedAnimation(
        parent: _controller!,
        curve: Curves.easeInOutSine,
      ));

      _animation?.addListener(_updateOffsetX);
      // 启动动画
      _controller?.repeat(
        reverse: true,
      );
    } else if (widget.direction == Axis.vertical &&
        startAnimateHeight != null &&
        contentSize.height > startAnimateHeight) {
      _controller?.stop();
      final animateValue = contentSize.height - startAnimateHeight;

      autoWidth = contentSize.width;
      autoHeight = startAnimateHeight;
      scaleDown = animateValue.abs() < scaleDownValue;
      offsetX = (autoWidth - contentSize.width) * 0.5;
      // print("开始动画 vertical scaleDownValue = $scaleDownValue");
      if (scaleDown) {
        offsetY = 0;
        setState(() {});
        _controller?.stop();
        return;
      }
      // print("开始动画 vertical scaleDown = $scaleDown");
      final animateSec = (animateValue / 4).ceil();
      _controller ??= AnimationController(
        vsync: this,
      );
      _controller?.duration = Duration(seconds: animateSec);
      _animation?.removeListener(_updateOffsetX);
      _animation?.removeListener(_updateOffsetY);
      _animation =
          Tween<double>(begin: 0.0, end: animateValue).animate(CurvedAnimation(
        parent: _controller!,
        curve: Curves.easeInOutSine,
      ));
      _animation?.addListener(_updateOffsetY);
      // 启动动画
      _controller?.repeat(
        reverse: true,
      );
    } else {
      setState(() {
        autoWidth = contentSize.width;
        autoHeight = contentSize.height;
        offsetX = 0;
        offsetY = 0;
      });
      _controller?.stop();
    }
  }

  // 更新横向偏移
  void _updateOffsetX() {
    setState(() {
      offsetX = -_animation!.value;
    });
  }

  // 更新纵向偏移
  void _updateOffsetY() {
    setState(() {
      offsetY = -_animation!.value;
    });
  }
}
